#include "head.h"

// 菜单信息 - 登陆用
const wchar_t *title = L"普通用户菜单";
const wchar_t *option_1[] = {L"登录", L"注册", L"返回"};

// 菜单信息 - 管理员用
const wchar_t *title_root = L"用户菜单";
const wchar_t *option_root[] = {
    L"设定航班",
    L"修改航班",
    L"修改普通用户",
    L"增加超级用户",
    L"退出"};

// 菜单信息 - 普通用户用
const wchar_t *title_user = L"用户菜单";
const wchar_t *option_user[] = {
    L"购票退票",
    L"余额充值",
    L"查看航班",
    L"修改密码",
    L"我的订单",
    L"退出"};

// 管理员 - 设定航班
int set_flight(F_list *list)
{
    F_data data;
    printf("请输入您要增加的航班班次");
    scanf("%d", &data.id);

    printf("请输入您要增加的飞机机型");
    scanf("%s", data.flighttype);

    printf("请输入您要增加的航班起点站");
    scanf("%s", data.startcity);

    printf("请输入您要增加的航班终点站");
    scanf("%s", data.arrivecity);

    printf("请输入您要增加的起飞时间 时:分");
    scanf("%d:%d", &data.starttime[0], &data.starttime[1]);

    printf("请输入您要增加的到达时间 时:分");
    scanf("%d:%d", &data.arrivetime[0], &data.arrivetime[1]);

    printf("请输入您要增加的飞行时间");
    scanf("%s", data.flytime);

    printf("请输入您要增加的票价");
    scanf("%d", &data.value);

    printf("请输入您要增加的额定载客量");
    scanf("%d", &data.maxNUM);

    printf("请输入您要增加的剩余座位数量");
    scanf("%d", &data.leftbuyersa);

    printf("请输入您要增加的是否起飞 ‘y’ ‘n’");
    scanf("%c", &data.whetherfly);

    D_List_insert(list, data, 1);
    D_List_file_print(list);
    return 0;
}
// 管理员 - 修改航班
void change_Flight(F_list *list)
{
    D_List_print(list);
    int id, id_2;        // 航班班次
    int starttime_2[2];  // 起飞时间 时:分
    int arrivetime_2[2]; // 到达时间 时:分
    char whetherfly_2;   // 是否起飞 ‘y’ ‘n’
    int sign = 0;
    F_node *data_2 = NULL;
    printf("输入您需要修改的航班信息：\n(1)修改航班班次\n(2)修改起飞时间\n(3)修改到达时间\n(4)修改飞行状态\n");
    scanf("%d", &sign);
    switch (sign)
    {
    case 1:
        printf("请输入你要修改的航班班次：");
        scanf("%d", &id);

        data_2 = D_List_find_id(list, id);
        printf("%d", data_2->data.id);
        printf("请输入你要改为的航班班次");
        scanf("%d", &id_2);
        data_2->data.id = id_2;

        printf("修改成功\n");

        printf("修改后的航班班次为：%d", data_2->data.id);
        D_List_file_print(list);
        break;
    case 2:
        printf("请输入你要修改的航班班次：");
        scanf("%d", &id);
        data_2 = D_List_find_id(list, id);

        printf("请输入新的起飞时间：");
        scanf("%d:%d", &starttime_2[0], &starttime_2[1]);
        for (size_t i = 0; i < 2; i++)
        {
            data_2->data.starttime[i] = starttime_2[i];
        }

        printf("修改成功\n");

        printf("修改后的航班起飞时间为：%d:%d\n", starttime_2[0], starttime_2[1]);
        D_List_file_print(list);
        break;
    case 3:
        printf("请输入你要修改的航班班次：");
        scanf("%d", &id);
        data_2 = D_List_find_id(list, id);

        printf("请输入新的到达时间：");
        scanf("%d:%d", &arrivetime_2[0], &arrivetime_2[1]);
        for (size_t i = 0; i < 2; i++)
        {
            data_2->data.arrivetime[i] = arrivetime_2[i];
        }
        printf("修改成功\n");

        printf("修改后的航班到达时间为：%d:%d\n", arrivetime_2[0], arrivetime_2[1]);
        D_List_file_print(list);
        break;
    case 4:
        printf("请输入你要修改的航班班次：");
        scanf("%d", &id);
        data_2 = D_List_find_id(list, id);

        printf("请输入新起飞状态：");
        getchar();
        scanf("%c", &whetherfly_2);
        data_2->data.whetherfly = whetherfly_2;
        printf("修改成功\n");

        printf("修改后的航班起飞状态为：%c\n", whetherfly_2);
        D_List_file_print(list);
        break;
    default:
        break;
    }
}
// 管理员 - 修改普通用户
void change_massage(FlightSystem *flight)
{
    U_list *f = S_List_init();
    U_list *F;

    f = flight->ADMIN_USER;
    f = S_List_merge(f, flight->GOLD_USER);
    f = S_List_merge(f, flight->PLATINUM_USER);
    f = S_List_merge(f, flight->REGULAR_USER);
    f = S_List_merge(f, flight->SILVER_USER);

    S_List_print(f);
    char name_2[64];
    char name[16];   // 用户名
    char passwd[64]; // 用户密码
    int flag = 0;
    printf("请输入您要修改的用户信息：\n(1)修改用户名\n(2)修改用户密码\n");
    scanf("%d", &flag);
    switch (flag)
    {
    case 1:
        printf("请输入你要修改的用户名:");
        scanf("%s", name);

        U_node *data_1 = S_List_find_name(f, name);
        printf("请输入新的用户名：");
        scanf("%s", name_2);
        F = judge_grade(flight, data_1->data);
        data_1 = S_List_find_name(F, name);
        strcpy(data_1->data.name, name_2);
        printf("修改成功！\n新的用户名为%s\n", name_2);
        S_List_File_print(F, By_Data_Judge_File(data_1->data));
        break;

    case 2:
        printf("请输入你要修改的用户名:");
        scanf("%s", name);

        U_node *data_2 = S_List_find_name(f, name);
        printf("请输入新的密码：");
        scanf("%s", passwd);
        F = judge_grade(flight, data_2->data);
        data_2 = S_List_find_name(F, name);
        strcpy(data_2->data.passwd, passwd);

        printf("修改成功！\n新的密码为%s", passwd);

        S_List_File_print(F, By_Data_Judge_File(data_2->data));
        break;

    default:
        break;
    }
}
// 管理员 - 增加超级用户
void add_superuser(FlightSystem *flight)
{
    U_data data;
    char passwd_2[64];
    printf("请输入你要注册的用户名：");
    scanf("%s", data.name);
    printf("请输入你的密码: ");
    scanf("%s", data.passwd);
    printf("请再次输入你的密码:\n");
    scanf("%s", passwd_2);

    if (strcmp(passwd_2, data.passwd))
    {
        printf("两次密码输入不相同 请重新运行本程序\n");
        exit(-1);
    }
    printf("恭喜你 注册成功\n");
    data.grade = 1;
    data.value = 0;

    // 插入到链表
    S_List_insert(flight->ADMIN_USER, data, 1);

    // 写入到文件
    S_List_File_print(flight->ADMIN_USER, ADMIN_FILE);
}

// 用户 买票
void Buy_Ticket(F_list *list, U_data *buyer_data)
{

    printf("****************************购票/退票****************************\n");
    F_node *ptr = NULL;
    D_List_print(list);
    int sign;
    int choice_num; // 选择的航班班次
    int c;
    char ch = 'n';
    char ch_3;
    char ch_2;
    while ('n' == ch)
    {

        printf("请选择'购票'还是'退票'\n\t(1)购票\n\t(2)退票\n\t(3)退出\n");
        scanf("%d", &sign);
        switch (sign)
        {
        case 1:
            while (1)
            {

                printf("开始购票!\n");
                printf("请输入你需要购买的航班班次： ");
                scanf("%d", &choice_num);
                // 判断余额是否足够，是否有剩余座位
                ptr = D_List_find_id(list, choice_num);
                if (NULL == ptr)
                {
                    printf("没有找到你要购买的航班班次，请确认你需要购买的航班班次\n");
                    break;
                }
                if (0 >= ptr->data.leftbuyersa)
                {
                    printf("该航班班次无座位，请你更换购买的航班班次\n");
                    break;
                }

                if (ptr->data.whetherfly == 'y')
                {
                    printf("飞机已起飞,请重新选择航班班次\n");
                    break;
                }
                if (ptr->data.whetherfly == 'y')
                {
                    printf("飞机已起飞,请重新选择航班班次\n");
                    break;
                }
                if (buyer_data->value >= ptr->data.value)
                {

                    buyer_data->value -= ptr->data.value;

                    printf("%d\n", buyer_data->value);
                    ptr->data.leftbuyersa--;
                    printf("购票成功！");
                    pos_insert_list(buyer_data->ticket, ptr->data);
                }
                else
                {
                    printf("余额不足,购票失败!");
                    break;
                }
                printf("是否退出购票 y or n \n");
                getchar();
                scanf("%c", &ch_2);
                if (ch_2 == 'y')
                {
                    break;
                }
            }

            // 向文件中写入航班信息
            D_List_file_print(list);
            break;
        // 退票
        case 2:
            while (1)
            {

                printf("开始退票!\n");
                printf("请输入你需要退票的航班班次： ");
                scanf("%d", &choice_num);
                c = find_by_id(buyer_data->ticket, choice_num);
                if (c != -1)
                {
                    ptr = D_List_find_id(list, choice_num);
                    buyer_data->value += ptr->data.value;
                    ptr->data.leftbuyersa++;
                    pos_del_list(buyer_data->ticket, c);
                    printf("退票成功！");
                }
                else
                {
                    printf("您没有购买该航班！");
                }
                printf("是否退出退票 y or n \n");
                getchar();
                scanf("%c", &ch_3);
                if (ch_3 == 'y')
                {
                    break;
                }
            }
            // 向文件中写入航班信息
            D_List_file_print(list);
            break;
        case 3:
            break;
        default:
            break;
        }
        printf("是否退出购票/退票 y or n \n");
        getchar();

        scanf("%c", &ch);
    }
}
// 用户 - 余额充值
void Recharge_balance(U_data *data)
{
    printf("****************************余额充值****************************\n");
    int money;
    printf("请输入您要充值的金额：");
    scanf("%d", &money);
    data->value = data->value + money;
    printf("充值成功!您的余额为:%d\n", data->value);
}
// 用户 - 修改密码
void change_password(U_data *data)
{
    printf("****************************修改密码****************************\n");
    char password[128];
    char pwd[128];
    printf("请输入你要修改的密码:\n");
    scanf("%s", password);
    printf("请再次输入你修改的密码:\n");
    scanf("%s", pwd);
    if (strcmp(password, pwd) != 0)
    {
        printf("两次密码输入不相同 请重新运行本程序\n");
        exit(-1);
    }
    strcpy(data->passwd, password);
    printf("修改后的密码为：%s\n", data->passwd);
    printf("修改成功！\n");
}
// 用户 - 我的订单
void my_older(U_data *data)
{
    printf("****************************我的订单****************************\n");
    if (data->ticket->len == 0)
    {
        printf("你当前还没有购票，没有订单\n");
    }
    else
    {
        printf_Sql_List(data->ticket);
    }
    sleep(2);
}

// 系统初始化
FlightSystem Sys_init(void)
{
    FlightSystem Flight_sys;
    Flight_sys.Flight_list = D_List_init();   // 航班信息
    Flight_sys.ADMIN_USER = S_List_init();    // 管理员账户信息
    Flight_sys.REGULAR_USER = S_List_init();  // 普通用户信息
    Flight_sys.SILVER_USER = S_List_init();   // 银卡会员信息 (9折)
    Flight_sys.GOLD_USER = S_List_init();     // 金卡会员信息 (8折)
    Flight_sys.PLATINUM_USER = S_List_init(); // 白金会员信息 (7折)

    // 从文件中导入数据
    D_List_file_scanf(Flight_sys.Flight_list);                  // 航班信息
    S_List_File_scanf(Flight_sys.ADMIN_USER, ADMIN_FILE);       // 管理员账户信息文件
    S_List_File_scanf(Flight_sys.REGULAR_USER, REGULAR_FILE);   // 普通用户信息文件
    S_List_File_scanf(Flight_sys.SILVER_USER, SILVER_FILE);     // 银卡会员信息文件 (9折)
    S_List_File_scanf(Flight_sys.GOLD_USER, GOLD_FILE);         // 金卡会员信息文件 (8折)
    S_List_File_scanf(Flight_sys.PLATINUM_USER, PLATINUM_FILE); // 白金会员信息文件 (7折)

    system("clear");
    return Flight_sys;
}
// 通过数据来判断文件
char *By_Data_Judge_File(U_data data)
{
    switch (data.grade)
    {
    case GRADE_ADMIN:
        return ADMIN_FILE;
    case GRADE_REGULAR:
        return REGULAR_FILE;
    case GRADE_GOLD:
        return GOLD_FILE;
    case GRADE_PLATINUM:
        return PLATINUM_FILE;
    case GRADE_SILVER:
        return SILVER_FILE;
    }
    return NULL;
}
// 系统登录
U_data Sys_log_in(FlightSystem Flight_sys)
{
    // 用户信息合表
    U_list *list = S_List_init();
    list = S_List_merge(list, Flight_sys.ADMIN_USER);    // 管理员账户信息文件
    list = S_List_merge(list, Flight_sys.REGULAR_USER);  // 普通用户信息文件
    list = S_List_merge(list, Flight_sys.SILVER_USER);   // 银卡会员信息文件 (9折)
    list = S_List_merge(list, Flight_sys.GOLD_USER);     // 金卡会员信息文件 (8折)
    list = S_List_merge(list, Flight_sys.PLATINUM_USER); // 白金会员信息文件 (7折)

    int num = 0;
    printf("1:进入注册\t 2:进入登录");
    scanf("%d", &num);

    switch (num)
    {
    case 1:
        reg(list); // 注册
        break;
    case 2:
        return Log_in(list); // 登录
    default:
        break;
    }

    sleep(3);
    // 开始登录
    U_data log_data = Log_in(list);

    printf("%d\n", log_data.ticket->len);
    return log_data;
}
// 判断用户等级
U_list *judge_grade(FlightSystem *Flight_sys, U_data sign)
{
    switch (sign.grade)
    {
    case 1:
        return Flight_sys->ADMIN_USER;
        break;
    case 2:
        return Flight_sys->REGULAR_USER;
        break;
    case 3:
        return Flight_sys->SILVER_USER;
        break;
    case 4:
        return Flight_sys->GOLD_USER;
        break;
    case 5:
        return Flight_sys->PLATINUM_USER;
        break;
    default:
        return NULL;
        break;
    }
}
// 替换
void lianbiao(U_list *list_1, U_data data)
{
    if (list_1 == NULL)
    {
        printf("链表为NULL\n");
        return;
    }
    if (list_1->next == NULL)
    {
        ERRLOG("表的数据为空");
    }
    U_node *ptr = list_1->next;

    while (ptr != NULL)
    {
        if (strcmp(ptr->data.name, data.name) == 0)
        {
            ptr->data = data;
            break;
        }
        ptr = ptr->next;
    }
    return;
}
// 判断用户等级并写入文件
void writing(U_list *list_2, FlightSystem *Flight_sys)
{
    if (list_2 == Flight_sys->REGULAR_USER)
        S_List_File_print(list_2, REGULAR_FILE);

    if (list_2 == Flight_sys->ADMIN_USER)
        S_List_File_print(list_2, ADMIN_FILE);

    if (list_2 == Flight_sys->SILVER_USER)
        S_List_File_print(list_2, SILVER_FILE);

    if (list_2 == Flight_sys->GOLD_USER)
        S_List_File_print(list_2, GOLD_FILE);

    if (list_2 == Flight_sys->PLATINUM_USER)
        S_List_File_print(list_2, PLATINUM_FILE);
}

// 系统菜单
void Sys_menu(FlightSystem *Flight_sys, U_data log_data)
{
    // 分支

    int flag = 0;

    switch (log_data.grade)
    {
    case 1:
        // 管理员功能界面
        printf("欢迎管理员用户登陆\n");
        flag = display_menu(title_root, option_root, 5);
        break;
    default:
        // 普通用户功能界面
        printf("欢迎普通用户登陆\n");
        flag = display_menu(title_user, option_user, 6) + 5;
        break;
    }

    U_list *list_2;
    // 菜单选项分支处理

    if (flag < 5)
    {
        while (1)
        {
            switch (flag)
            {
            case 1:
                // 管理员 - 设定航班
                set_flight(Flight_sys->Flight_list);

                break;
            case 2:
                // 管理员 - 修改航班
                change_Flight(Flight_sys->Flight_list);
                break;
            case 3:
                // 管理员 - 修改普通用户
                change_massage(Flight_sys);
                break;
            case 4:
                // 管理员 - 增加超级用户
                add_superuser(Flight_sys);
                break;
            case 5:
                exit(1); // 退出
            }
            flag = display_menu(title_root, option_root, 4);
        }
    }
    else
    {
        char num_1;
        flag = flag - 5;
        while (1)
        {
            switch (flag)
            {
            case 1:

                // 用户 - 购票退票
                list_2 = judge_grade(Flight_sys, log_data); // 判断用户等级
                Buy_Ticket(Flight_sys->Flight_list, &log_data);
                printf("%d\n", log_data.value);
                lianbiao(list_2, log_data);  // 将更改后的数据链表替换掉原来的
                writing(list_2, Flight_sys); // 写入文件中

                break;

            case 2:
                while (1)
                {

                    // 用户 - 余额充值
                    list_2 = judge_grade(Flight_sys, log_data);
                    Recharge_balance(&log_data);
                    lianbiao(list_2, log_data);
                    writing(list_2, Flight_sys);
                    printf("是否退出充值余额 y or n:");
                    scanf(" %c", &num_1);
                    if ('y' == num_1)
                        break;
                }
                break;

            case 3:

                // 用户 - 查看航班
                D_List_file_scanf(Flight_sys->Flight_list);
                D_List_print(Flight_sys->Flight_list);
                printf("是否退出！ y or n:");
                scanf(" %c", &num_1);

                break;
            case 4:
                while (1)
                {

                    // 用户 - 修改密码
                    list_2 = judge_grade(Flight_sys, log_data);
                    change_password(&log_data);
                    lianbiao(list_2, log_data);
                    writing(list_2, Flight_sys);
                    printf("是否继续修改密码 y or n:");
                    scanf(" %c", &num_1);
                    if ('y' == num_1)
                        break;
                }
                break;
            case 5:
                while (1)
                {
                    // 用户 - 我的订单
                    my_older(&log_data);
                    printf("是否退出查看我的订单 y or n:");
                    scanf(" %c", &num_1);
                    if ('y' == num_1)
                        break;
                }
                break;

            case 6:
                exit(1); // 退出

            default:
                break;
            }
            flag = display_menu(title_user, option_user, 6);
        }
    }
}